<template>
    <el-cascader
            ref="cascader"
            :value="value"
            :options="computedTreeData"
            :props="computedProps"
            v-bind="originProp"
            clearable
            filterable

            @dblclick.native="dblclick"
            v-on:focus="($event)=>{$emit('focus', $event)}"
            v-on:blur="($event)=>{$emit('blur', $event)}"
            v-on:change="(val)=>{$emit('change', val)}"
            v-on:input="(val)=>{$emit('input', val)}"
            v-loading="localLoading"
            element-loading-spinner="el-icon-loading"
    ></el-cascader>
</template>

<script>

    export default {
        name: 'StElCascader',
        props: {
            value: {},
            // 显示的名称，目前仅用于回显
            labelText: {
                type: String
            },
            // 被包装组件的原始属性
            originProp: {
                type: Object,
                default: function () {
                    return {}
                }
            },
            originProps: {
                type: Object,
                default: function () {
                    return {}
                }
            },
            // 缓存key，仅url加载有效
            cacheKey: String,
            // 自定义数据
            datas: {
                type: [Array, String],
                default: function () {
                    return []
                }
            },
        },
        computed: {
            computedTreeData(){
                return this.$stArrayTools.listToTree(this.localData,null)
            },
            computedProps() {
                let defaultProps = {
                    value: 'id', // 选中的值属性
                    label: 'name', // 显示的值属性
                    children: 'children', // 子节点属性
                    leaf: 'leaf', // 标识叶子节点
                    lazy: false,
                    lazyLoad: this.lazyLoad
                }

                let r = this.$stObjectTools.extendDeep(defaultProps, this.originProps)
                return r
            }
        },
        data() {
            return {
                localData: [],
                localLazyLoadData: [],
                localLoading: false
            }
        },
        mounted() {
            this.initLabelText(this.labelText)
            this.initData(this.datas)

        },
        methods: {
            selectedDataEmit(val) {
                this.$emit('data', this.getSelectData(val))
            },
            // 获取选中的数据本身
            getSelectData(val) {
                if (val == null || val == undefined) {
                    return null
                }
                let array = this.$stArrayTools.treeToList([].concat(this.localData,this.localLazyLoadData))
                if (this.$stStringTools.isString(val)) {
                    return array.filter(item => val == this.$stObjectTools.getValue(item, this.computedProps.value)).pop() || null
                }
                return array.filter(item => val.some(valItem => valItem == this.$stObjectTools.getValue(item, this.computedProps.value)))
            },
            // 根据url加载数据
            initDataByUrl(url) {
                if(this.cacheKey){
                    let data = this.$stStorageTools.get(this.cacheKey)
                    if(data){
                        this.localData = data
                        return
                    }
                }
                this.localLoading = true
                this.axios.get(url).then(res => {
                    this.localData = res.data
                    if(this.cacheKey){
                        this.$stStorageTools.set(this.cacheKey,res.data)
                    }
                }).catch(error => {
                    this.localData = []
                    if (error.response) {
                        if (error.response.status == 401) {
                            return
                        }
                        if(error.response.data && error.response.data.errorMsg){
                            if (error.response.status != 404) {
                                this.$message.error(error.response.data.errorMsg)
                            }
                        }

                    } else {
                        this.$message.error('网络错误或服务不可用')
                    }
                }).finally(()=>{
                    this.localLoading = false
                })
            },
            // 加载
            initData(data) {
                if (!data) {
                    return
                }
                if (this.$stArrayTools.isArray(data)) {
                    this.localData = data
                } else if (this.$stStringTools.isString(data)) {
                    this.initDataByUrl(data)
                } else if (this.$stFunctionTools.isFunction(data)) {
                    this.initData(data())
                }
            },
            lazyLoad(node, resolve) {
                this.$emit('lazyLoadingBegin', node.data)
                let params = {parentId: this.$stObjectTools.getValue(node.data, this.computedProps.value)}
                this.axios.get(this.datas, {params: params})
                    .then((response) => {
                        let content = response.data
                        this.localLazyLoadData = this.localLazyLoadData.concat(content)
                        resolve(content)
                        this.$emit('lazyLoadingEnd', node.data, content)
                    })
                    .catch((error) => {
                        resolve([])
                        this.$emit('lazyLoadingEnd', node.data, [])
                        if (error.response) {
                            if (error.response.status == 401) {
                                return
                            }
                            if(error.response.data && error.response.data.errorMsg){
                                if (error.response.status != 404) {
                                    this.$message.error(error.response.data.errorMsg)
                                }
                            }

                        } else {

                            this.$message.error('网络错误或服务不可用')
                        }
                    }).finally(() => {

                })
            },
            // 初始化回显
            initLabelText(labelText) {
                if(labelText){
                    // 斩不支持多选回显
                    let cascader = this.$refs.cascader
                    if(cascader){
                        let input = cascader.$el.getElementsByTagName("input")[0]
                        input.value = labelText
                    }
                }
            },
          dblclick(){
            this.initData(this.datas)
          }
        },
        watch: {
            datas(val) {
                this.initData(val)
            },
            value(val) {
                this.selectedDataEmit(val)
            },
            localData() {
                this.selectedDataEmit(this.value)
            },
            labelText(val){
                this.initLabelText(val)
            }
        }
    }
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>
